package com.example.webdownloadserver.core.excel;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;


import com.example.webdownloadserver.common.TaskConstants;
import com.example.webdownloadserver.constants.TaskCenterConstants;
import com.example.webdownloadserver.service.TaskCenterService;
import com.example.webdownloadserver.vo.TaskCenter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.dnkj.download.task.util.Sysdate;

/**
 * 
 * <p>
 * 导出模板
 * </p>
 * @title TemplateExcelExport.java
 * @package com.dnkj.download.task.core.excel 
 * @author ying.xiao
 * @version 0.1 2020年12月5日
 */
public class TemplateExcelExport {
	

	
    private Logger logger = LoggerFactory.getLogger(TemplateExcelExport.class);
	
	protected ExcelExportIface service = null;
	protected TaskCenter taskCenter;
	protected TaskCenterService taskCenterService = null;
	protected String fileName = null;
	
	public TemplateExcelExport(ExcelExportIface service, TaskCenterService taskCenterService, TaskCenter taskCenter, String fileName) {
		super();
		this.service = service;
		this.taskCenter = taskCenter;
		this.taskCenterService = taskCenterService;
		this.fileName = fileName;
		if (service == null) {
			throw new RuntimeException("excelExport service 注入失败");
		}
	}
	/**
	 * 
	 * <p>
	 * 导出本地
	 * </p>
	 * @author ying.xiao
	 * @version 0.1 2020年12月5日
	 * @param pojoClass
	 * @param param
	 * @throws Exception
	 * void
	 */
	public void doExcelExport(Class<?> pojoClass,Map<String,Object> param) throws Exception{
		long startTime,totalStart;
		long endTime,totalEnd;
		totalStart = System.currentTimeMillis();
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",操作时间："+ taskCenter.getTaskCreateTime());
		com.dnkj.download.task.core.excel.ExcelExportHandler handler = new com.dnkj.download.task.core.excel.ExcelExportHandler(pojoClass);
        //分页查询
        SXSSFWorkbook wb = handler.getWorkbook();
        //查询总数
        int maxNum = service.queryListCount(param);
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",数据总数："+maxNum);
        int k = 1;
		int max = (int) (maxNum + TaskCenterConstants.EXPORT_MAX_EXCEL_MAX - 1)/ TaskCenterConstants.EXPORT_MAX_EXCEL_MAX;
		int maxSheet = (int) (maxNum + TaskCenterConstants.MAX_SHEET_NUM - 1)/ TaskCenterConstants.MAX_SHEET_NUM;
   		for (int i = 1; i <= maxSheet; i++) {
			String sheetName = "DATA_"+String.valueOf(i);
			wb.createSheet(sheetName);
			handler.createExcel(wb, sheetName);
			for(;k<=max;k++) {
				if(wb.getSheet(sheetName).getPhysicalNumberOfRows() >= (TaskCenterConstants.MAX_SHEET_NUM+1)) {
					break;
				}
				startTime = System.currentTimeMillis();
				logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",开始 "+ i + "_" + k 
						+ "次下载数据list，当前时间："+ Sysdate.getTimeStr(true));
				
				Collection<?> list = service.queryListPage(param,k,TaskCenterConstants.EXPORT_MAX_EXCEL_MAX);
		   		
		   		endTime = System.currentTimeMillis();
		   		logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",结束"+ i + "_" + k 
		   				+ "次下载数据list:"+list.size()+"，当前时间:"+Sysdate.getTimeStr(true)+",耗时【"+(endTime-startTime)+"】毫秒");
	    		
		   		handler.writeExcel(list, wb, wb.getSheet(sheetName).getPhysicalNumberOfRows(), sheetName);
		   		
			}		
   		}
   		if (wb != null) {
			try {
                //写Excel文件
                String folder = Sysdate.getDateStr(true);
                String dir = TaskConstants.DOWNLOADPATH + File.separator + folder;
                File outDir = new File(dir);
                outDir.mkdirs();
                String filePath = dir + File.separator + fileName + ".xls";
                FileOutputStream outputStream = new FileOutputStream(filePath);
                wb.write(outputStream);
                wb.close();
                //更新下载中心记录
                taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_SUCC);
                taskCenter.setTaskSaveType(TaskCenterConstants.TASK_SAVE_TYPE_DISK);
                taskCenter.setTaskCleanFlag(TaskCenterConstants.TASK_CLEAN_FLAG_CAN);
                taskCenter.setTaskFileName(fileName + ".xls");
                taskCenter.setTaskDownUrl(filePath);
                taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_SUCC);
    			totalEnd = System.currentTimeMillis();
    			logger.info(fileName+"下载完成|操作人：:"+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",当前时间："+Sysdate.getTimeStr(true)+",共耗时【"+(totalEnd-totalStart)+"】毫秒");
			} catch (Exception e) {
				logger.error(fileName+"下载导出文件异常",e);
	            taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_FAIL);
	            taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_IOEERROR);
			} finally {
				if (null != wb) {
					wb.close();
				}
			}
   		}
   		taskCenterService.update(taskCenter);
	}
	/**
	 * 
	 * <p>
	 * 导出oss
	 * </p>
	 * @author ying.xiao
	 * @version 0.1 2020年12月5日
	 * @param pojoClass
	 * @param param
	 * @throws Exception
	 * void
	 */
	public void doExcelExportOss(Class<?> pojoClass,Map<String,Object> param,String path) throws Exception{
		long startTime,totalStart;
		long endTime,totalEnd;
		totalStart = System.currentTimeMillis();
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",操作时间："+ taskCenter.getTaskCreateTime());
		com.dnkj.download.task.core.excel.ExcelExportHandler handler = new com.dnkj.download.task.core.excel.ExcelExportHandler(pojoClass);
        //分页查询
        SXSSFWorkbook wb = handler.getWorkbook();
        //查询总数
        int maxNum = service.queryListCount(param);
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",数据总数："+maxNum);
        int k = 1;
		int max = (int) (maxNum + TaskCenterConstants.EXPORT_MAX_EXCEL_MAX - 1)/ TaskCenterConstants.EXPORT_MAX_EXCEL_MAX;
		int maxSheet = (int) (maxNum + TaskCenterConstants.MAX_SHEET_NUM - 1)/ TaskCenterConstants.MAX_SHEET_NUM;
   		for (int i = 1; i <= maxSheet; i++) {
			String sheetName = "DATA_"+String.valueOf(i);
			wb.createSheet(sheetName);
			handler.createExcel(wb, sheetName);
			for(;k<=max;k++) {
				if(wb.getSheet(sheetName).getPhysicalNumberOfRows() >= (TaskCenterConstants.MAX_SHEET_NUM+1)) {
					break;
				}
				startTime = System.currentTimeMillis();
				logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",开始 "+ i + "_" + k 
						+ "次下载数据list，当前时间："+ Sysdate.getTimeStr(true));
				
				Collection<?> list = service.queryListPage(param,k,TaskCenterConstants.EXPORT_MAX_EXCEL_MAX);
		   		
		   		endTime = System.currentTimeMillis();
		   		logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",结束"+ i + "_" + k 
		   				+ "次下载数据list:"+list.size()+"，当前时间:"+Sysdate.getTimeStr(true)+",耗时【"+(endTime-startTime)+"】毫秒");
	    		
		   		handler.writeExcel(list, wb, wb.getSheet(sheetName).getPhysicalNumberOfRows(), sheetName);
		   		
			}		
   		}
   		if (wb != null) {
			try {
                fileName= fileName + ".xls";
//                String filePath = OssUtil.uploadFile2OSS(workbookConvertorStream(wb), fileName, path, null);
              
                //更新下载中心记录
                taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_SUCC);
                taskCenter.setTaskSaveType(TaskCenterConstants.TASK_SAVE_TYPE_DISK);
                taskCenter.setTaskCleanFlag(TaskCenterConstants.TASK_CLEAN_FLAG_CAN);
                taskCenter.setTaskFileName(fileName);
//                taskCenter.setTaskDownUrl(filePath);
                taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_SUCC);
    			totalEnd = System.currentTimeMillis();
    			logger.info(fileName+"下载完成|操作人：:"+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",当前时间："+Sysdate.getTimeStr(true)+",共耗时【"+(totalEnd-totalStart)+"】毫秒");
			} catch (Exception e) {
				logger.error(fileName+"下载导出文件异常",e);
	            taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_FAIL);
	            taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_IOEERROR);
			} finally {
				if (null != wb) {
					wb.close();
				}
			}
   		}
   		taskCenterService.update(taskCenter);
	}
	
	
	
	private InputStream workbookConvertorStream(SXSSFWorkbook wb) {
		  InputStream in = null;
		    try{
		        //临时缓冲区
		        ByteArrayOutputStream out = new ByteArrayOutputStream();
		        //创建临时文件
		        wb.write(out);
		        byte [] bookByteAry = out.toByteArray();
		        in = new ByteArrayInputStream(bookByteAry);
		    }
		    catch (Exception e){
		        e.printStackTrace();
		    }
		    return in;
	}

	public void doExcelExportByDate(Class<?> pojoClass,Map<String,Object> param) throws Exception{
		fileName = fileName +"-"+ taskCenter.getTaskOperator()+"-"+(int)(Math.random()*900)+100;;
		long startTime,totalStart;
		long endTime,totalEnd;
		totalStart = System.currentTimeMillis();
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",操作时间："+ taskCenter.getTaskCreateTime());
		com.dnkj.download.task.core.excel.ExcelExportHandler handler = new com.dnkj.download.task.core.excel.ExcelExportHandler(pojoClass);
        //分页查询
        SXSSFWorkbook wb = handler.getWorkbook();
        int sheetDataCount = 0;
        logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam());
        int k = 1;
		List<String> dateList = Sysdate.getBetweenDays(param.get("queryBeginTime").toString(), param.get("queryEndTime").toString(), false);
		String sheetName = "DATA_"+String.valueOf(k);
		createSheet(wb, handler, sheetName);
   		for (String date : dateList) {
			if(sheetDataCount >= (TaskCenterConstants.MAX_SHEET_NUM+1)) {
				k++;
				sheetName = "DATA_"+String.valueOf(k);
				createSheet(wb, handler, sheetName);
				sheetDataCount = 0;
			}
			param.put("queryBeginTime",date);
			param.put("queryEndTime",date + " 23:59:59");
			startTime = System.currentTimeMillis();
			logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",开始 日期"+ date + "下载数据list，当前时间："+ Sysdate.getTimeStr(true));
			
			Collection<?> list = service.queryListPage(param,null,null);
			sheetDataCount += CollectionUtils.isNotEmpty(list)?list.size():0;
	   		
	   		endTime = System.currentTimeMillis();
	   		logger.info(fileName+"下载|操作人："+taskCenter.getTaskOperator()+",结束 日期"+ date + "下载数据list:"+list.size()+"，当前时间:"+Sysdate.getTimeStr(true)+",耗时【"+(endTime-startTime)+"】毫秒");
	   		if(CollectionUtils.isEmpty(list)) {
	   			continue;
	   		}
	   		
	   		handler.writeExcel(list, wb, wb.getSheet(sheetName).getPhysicalNumberOfRows(), sheetName);
   		}
   		if (wb != null) {
			try {
                //写Excel文件
                String folder = Sysdate.getDateStr(true);
                String dir = TaskConstants.DOWNLOADPATH + File.separator + folder;
                File outDir = new File(dir);
                outDir.mkdirs();
                String filePath = dir + File.separator + fileName + ".xls";
                FileOutputStream outputStream = new FileOutputStream(filePath);
                wb.write(outputStream);
                wb.close();
                //更新下载中心记录
                taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_SUCC);
                taskCenter.setTaskSaveType(TaskCenterConstants.TASK_SAVE_TYPE_DISK);
                taskCenter.setTaskCleanFlag(TaskCenterConstants.TASK_CLEAN_FLAG_CAN);
                taskCenter.setTaskFileName(fileName + ".xls");
                taskCenter.setTaskDownUrl(filePath);
                taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_SUCC);
    			totalEnd = System.currentTimeMillis();
    			logger.info(fileName+"下载完成|操作人：:"+taskCenter.getTaskOperator()+",参数："+taskCenter.getTaskParam()+",当前时间："+Sysdate.getTimeStr(true)+",共耗时【"+(totalEnd-totalStart)+"】毫秒");
			} catch (Exception e) {
				logger.error(fileName+"下载导出文件异常",e);
	            taskCenter.setTaskStatus(TaskCenterConstants.TASK_STATUS_FAIL);
	            taskCenter.setTaskRemark(TaskConstants.DOWNLOAD_IOEERROR);
			} finally {
				if (null != wb) {
					wb.close();
				}
			}
   		}
   		taskCenterService.update(taskCenter);
	}

	private void createSheet(SXSSFWorkbook wb, com.dnkj.download.task.core.excel.ExcelExportHandler handler, String sheetName) {
		wb.createSheet(sheetName);
		handler.createExcel(wb, sheetName);
	}


}

